package com.quanyan.club.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.club.entity.db.*;
import com.quanyan.club.entity.vo.resp.RespClubMemberCardInfo;
import com.quanyan.club.entity.vo.resp.RespClubMemberSortList;
import com.quanyan.club.mapper.*;
import com.quanyan.club.service.ClubMemberSearchBizService;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.Limit;
import com.quanyan.search.entity.request.ReqClubMemberInfo;
import com.quanyan.search.entity.response.ClubMemberResponse;
import com.quanyan.search.service.impl.ClubMemberSearchServiceImpl;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.serviceFacade.UserServiceFacade;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by zhuo.shi on 2016/12/5.
 */
@Service
public class ClubMemberSearchBizServiceImpl extends BaseServiceImpl implements ClubMemberSearchBizService {

    private static Logger logger = LoggerFactory.getLogger(ClubMemberSearchBizServiceImpl.class);

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
    @Autowired
    private UserServiceFacade userServiceFacade;
    @Autowired
    private TbClubMapper clubMapper;
    @Autowired
    private TbClubActivityMapper clubActivityMapper;
    @Autowired
    private TbOrderMapper orderMapper;
    @Autowired
    private TbActivityMapper activityMapper;
    @Autowired
    private TbClubMemberMapper tbClubMemberMapper;
    @Autowired
    private ClubMemberMapper clubMemberMapper;
    @Autowired
    private TbClubMemberQuitRecordMapper clubMemberQuitRecordMapper;

    private ClubMemberSearchServiceImpl clubMemberSearchService;

    @PostConstruct
    protected  void init(){
        clubMemberSearchService = new ClubMemberSearchServiceImpl();
        clubMemberSearchService.setURL(searchCloudUrl);
    }

    /**
     * 记录表成员列表搜索
     * @param clubId    俱乐部id
     * @param nickName  俱乐部成员昵称
     * @return
     */
    @Override
    public List<RespClubMemberCardInfo> searchClubMember(int clubId, String nickName) {

        nickName = nickName.trim();
        
        List<RespClubMemberCardInfo> cardInfos = new ArrayList<>();

        ReqClubMemberInfo searchInfo = new ReqClubMemberInfo();
        searchInfo.setClub_id(clubId);
        searchInfo.setClub_member_nickname(nickName);
        APIResponse<List<ClubMemberResponse>> response = clubMemberSearchService.searchClubMemberInfoList(searchInfo);
        if (!response.isRet()) {
            return cardInfos;
        }
        List<ClubMemberResponse> searchResult = response.getData();
        List<Integer> uids = new ArrayList<>();
        for (ClubMemberResponse m : searchResult) {
            uids.add(Integer.valueOf(m.getClub_member_uid()));
        }

        Map<Integer, RespUserInfoBase> userInfMap = userServiceFacade.batchQueryUserInfoToMap(uids);
        for (ClubMemberResponse m : searchResult) {
            RespClubMemberCardInfo info = new RespClubMemberCardInfo();
            Integer uid = Integer.valueOf(m.getClub_member_uid());
            RespUserInfoBase userInfo = userInfMap.get(uid);

            info.setUid(uid);
            info.setClubId(clubId);
            if (userInfo != null) {
                info.setUsername(userInfo.getNickName());
                info.setAvatar(userInfo.getIcon());
                info.setMobile(userInfo.getMobile());
                info.setGender(userInfo.getGender());
            }
            TbClubMember clubMember = super.getClubMember(uid, clubId);
            if (clubMember != null){
                info.setRoleCode(clubMember.getRoleCode());
                info.setRoleName(clubMember.getRoleName());
                info.setMemberLabelName(clubMember.getMemberLabelName());
                info.setRemarkname(clubMember.getRemarkName());
                info.setTeamMember(clubMember.getIsTeamMember()==1);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date createTime = clubMember.getCreateTime();
                try {
                    createTime = sdf.parse(sdf.format(createTime));
                    Date now = new Date();
                    now = sdf.parse(sdf.format(now));
                    long days = (now.getTime() - createTime.getTime()) / (1000 * 3600 * 24);
                    info.setJoinDays((int)days+1);
                }catch (Exception e){
                }
            }
            info.setSignupCount(clubMemberMapper.countMemberJionClubActivityCount(clubId, uid));

            populateLatestSignUpActivityInfo(info);

            cardInfos.add(info);
        }

        return cardInfos;
    }

    /**
     * 获取用户在某俱乐部参加活动的场次
     */
    private int getSignUpActivityCount(int clubId, int uid){
        TbOrderExample orderExample = new TbOrderExample();
        orderExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andOrderUidEqualTo(uid)
                .andOrderStatusIn(Arrays.asList(((byte)2), (byte)6, (byte)7));
        List<TbOrder> orders =  orderMapper.selectByExample(orderExample);
        if (orders == null || orders.size() == 0){
            return 0;
        }
        List<Integer> activityIds = new ArrayList<>();
        for (TbOrder order : orders){
            activityIds.add(order.getActivityId());
        }
        List<Integer> withoutDupActIds = new ArrayList<>(new HashSet<>(activityIds));
        return withoutDupActIds.size();
    }

    /**
     * 俱乐部成员列表排序
     * @param clubId    俱乐部id
     * @param sortBy    排序规则 1 按加入天数降序排  2 按加入天升序排  3 按参加此俱乐部活动数数量降序排
     * @return
     */
    @Override
    public RespClubMemberSortList sortClubMember(int clubId, int sortBy, int pageNo, int pageSize) {

        RespClubMemberSortList sortList = new RespClubMemberSortList();

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("clubId", clubId);
        paramMap.put("sortBy", sortBy);

        Limit limit = Limit.buildLimit(pageNo, pageSize);
        paramMap.put("start", limit.getStart());
        paramMap.put("pageSize", pageSize);

        int total = clubMemberMapper.countClubMemberSortList(clubId);   //sqlSessionTemplate.selectOne("countClubMemberSortList", paramMap);

        List<RespClubMemberCardInfo> resultList = clubMemberMapper.queryClubMemberSortList(clubId, sortBy, limit.getStart(), pageSize);
                //sqlSessionTemplate.selectList("queryClubMemberSortList", paramMap);
        if (resultList == null || resultList.size() == 0){
            sortList.setMemberList(PageObj.create(0, pageNo, pageSize, resultList));
            return sortList;
        }

        List<Integer> uids = new ArrayList<>();
        for (RespClubMemberCardInfo info : resultList){
            uids.add(info.getUid());
        }
        Map<Integer, RespUserInfoBase> userMap = userServiceFacade.batchQueryUserInfoToMap(uids);
        for (RespClubMemberCardInfo info : resultList){

            RespUserInfoBase userInfo = userMap.get(info.getUid());     //用户信息
            if (userInfo != null){
                info.setJoinDays(info.getJoinDays()+1);
                info.setAvatar(userInfo.getIcon());
                info.setGender(userInfo.getGender());
                info.setMobile(userInfo.getMobile());
                info.setUsername(userInfo.getNickName());
            }

            populateLatestSignUpActivityInfo(info); //填充活动信息
        }

        sortList.setMemberList(PageObj.create(total, pageNo, pageSize, resultList));
        if (pageNo == 1){
            populateClubMemberSortList(clubId, sortList);
        }

        return sortList;
    }

    /**
     * 填充俱乐部人数统计
     */
    private void populateClubMemberSortList(int clubId, RespClubMemberSortList sortList){

        TbClubMemberExample memberExample = new TbClubMemberExample();
        memberExample.createCriteria().andClubIdEqualTo(clubId).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        List<TbClubMember> clubMembers = tbClubMemberMapper.selectByExample(memberExample);
        if (clubMembers == null || clubMembers.size() == 0){
            return;
        }
        List<Integer> uids = new ArrayList<>();
        for (TbClubMember member : clubMembers){
            uids.add(member.getUid());
        }
        Map<Integer, RespUserInfoBase> userInfoMap = userServiceFacade.batchQueryUserInfoToMap(uids);
        int maleCount = 0;
        int femaleCount = 0;
        for (Integer uid : uids){
            RespUserInfoBase userInfo = userInfoMap.get(uid);
            if (userInfo == null){
                continue;
            }
            int gender = userInfo.getGender();
            if (gender == 1){ //男
                maleCount += 1;
            }
            if (gender == 2){ //女
                femaleCount += 1;
            }
        }
        sortList.setTotalMemberCount(uids.size());

        sortList.setMaleMemberCount(maleCount);
        sortList.setFemaleMemberCount(femaleCount);

        Date monthBegin = DateUtils.getTimesMonthmorning();
        Date monthEnd = DateUtils.getTimesMonthnight();
        memberExample.clear();
        memberExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andCreateTimeGreaterThanOrEqualTo(monthBegin)
                .andCreateTimeLessThan(monthEnd)
                .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
        int incrCount = tbClubMemberMapper.countByExample(memberExample);
        sortList.setIncrMemberCount(incrCount);

        TbClubMemberQuitRecordExample quitRecordExample = new TbClubMemberQuitRecordExample();
        quitRecordExample.createCriteria()
                .andClubIdEqualTo(clubId)
                .andUpdateTimeGreaterThanOrEqualTo(monthBegin)
                .andUpdateTimeLessThan(monthEnd);
        int quitCount = clubMemberQuitRecordMapper.countByExample(quitRecordExample);
        sortList.setQuitMemberCount(quitCount);
    }

    /**
     * 参加此俱乐部最近一个活动的信息
     */
    private void populateLatestSignUpActivityInfo(RespClubMemberCardInfo info){

        int uid = info.getUid();
        int clubId = info.getClubId();

        TbClub tbClub = clubMapper.selectByPrimaryKey(clubId);
        if (uid == tbClub.getUid()){
            //此人是主席
            info.setClubFoundDays((int)(new Date().getTime() - tbClub.getCreateTime().getTime())/(1000*3600*24));
            TbClubActivityExample clubActivityExample = new TbClubActivityExample();
            clubActivityExample.createCriteria()
                    .andClubIdEqualTo(clubId)
                    .andActivityStatusNotEqualTo(3.0f)  //没取消的活动
                    .andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
            int pubulishActivityCount = clubActivityMapper.countByExample(clubActivityExample);
            info.setPublishActivityCount(pubulishActivityCount);
            return;
        }

        TbOrderExample example = new TbOrderExample();
        example.createCriteria()
                .andClubIdEqualTo(clubId)
                .andOrderUidEqualTo(uid)
                .andOrderStatusIn(Arrays.asList((byte)2, (byte)6, (byte)7));
        example.setOrderByClause(" create_time desc");

        List<TbOrder> orders = orderMapper.selectByExample(example);
        if (orders == null || orders.size() == 0){
            return;
        }
        Iterator<TbOrder> it = orders.iterator();
        while (it.hasNext()){
            TbOrder order = it.next();
            int activityId = order.getActivityId();
            TbActivity tbActivity = activityMapper.selectByPrimaryKey(activityId);
            if (tbActivity.getEndTime().before(new Date())){        //活动已经结束，排除
                it.remove();
            }
        }
        if (orders.size() == 0){
            return;
        }
        int activityId = orders.get(0).getActivityId();
        info.setLatestSignUpActivityDate(orders.get(0).getCreateTime());
        TbActivity tbActivity = activityMapper.selectByPrimaryKey(activityId);
        if (tbActivity != null){
            info.setLatestSignUpActivityName(tbActivity.getName());
        }
    }

}
